#include <stdbool.h>
#include <stdlib.h>
#include "preserve_bounds.h"
#include "utils.h"
#include "test_utils.h"
#include "mesh.h"
#include "sparse_mat.h"
#include "edges.h"

const char* test_case = "preserve bounds";

int main(void) {

  double positions[] = {
    -1., -1., -1.,
		-1., 0., 0.,
		-1., 1., 1.,
		0., 0.25, 0.25,
		0., -0.25, -0.25,
		1., -1., -1.,
		1., 0., 0.,
		1., 1., 1.,
		0., -1., -1.,
		0., 1., 1.
  };

  unsigned int face[] = {
    0, 1, 4,
    1, 3, 4,
    1, 2, 3,
    3, 6, 7,
    3, 4, 6,
    4, 5, 6,
    0, 8, 4,
    5, 4, 8,
    2, 3, 9,
    3, 9, 7
  };

  double q[] = {
    2., 2., 2., 2.,
    2., 2., 2., 2.,
    2., 2., 2., 2.,
    2., 2., 2., 2.,

    3., 3., 3., 3.,
    3., 3., 3., 3.,
    3., 3., 3., 3.,
    3., 3., 3., 3.,

    2., 2., 2., 2.,
    2., 2., 2., 2.,
    2., 2., 2., 2.,
    2., 2., 2., 2.,

    6., 6., 6., 6.,
    6., 6., 6., 6.,
    6., 6., 6., 6.,
    6., 6., 6., 6.,

    6., 6., 6., 6.,
    6., 6., 6., 6.,
    6., 6., 6., 6.,
    6., 6., 6., 6.,

    2., 2., 2., 2.,
    2., 2., 2., 2.,
    2., 2., 2., 2.,
    2., 2., 2., 2.,

    3., 3., 3., 3.,
    3., 3., 3., 3.,
    3., 3., 3., 3.,
    3., 3., 3., 3.,

    2., 2., 2., 2.,
    2., 2., 2., 2.,
    2., 2., 2., 2.,
    2., 2., 2., 2.,

    2., 2., 2., 2.,
    2., 2., 2., 2.,
    2., 2., 2., 2.,
    2., 2., 2., 2.,

    2., 2., 2., 2.,
    2., 2., 2., 2.,
    2., 2., 2., 2.,
    2., 2., 2., 2.
  };

  double q_old[] = {
    2., 2., 2., 2.,
    2., 2., 2., 2.,
    2., 2., 2., 2.,
    2., 2., 2., 2.,

    3., 3., 3., 3.,
    3., 3., 3., 3.,
    3., 3., 3., 3.,
    3., 3., 3., 3.,

    2., 2., 2., 2.,
    2., 2., 2., 2.,
    2., 2., 2., 2.,
    2., 2., 2., 2.,

    6., 6., 6., 6.,
    6., 6., 6., 6.,
    6., 6., 6., 6.,
    6., 6., 6., 6.,

    6., 6., 6., 6.,
    6., 6., 6., 6.,
    6., 6., 6., 6.,
    6., 6., 6., 6.,

    2., 2., 2., 2.,
    2., 2., 2., 2.,
    2., 2., 2., 2.,
    2., 2., 2., 2.,

    3., 3., 3., 3.,
    3., 3., 3., 3.,
    3., 3., 3., 3.,
    3., 3., 3., 3.,

    2., 2., 2., 2.,
    2., 2., 2., 2.,
    2., 2., 2., 2.,
    2., 2., 2., 2.,

    2., 2., 2., 2.,
    2., 2., 2., 2.,
    2., 2., 2., 2.,
    2., 2., 2., 2.,

    2., 2., 2., 2.,
    2., 2., 2., 2.,
    2., 2., 2., 2.,
    2., 2., 2., 2.
  };

  Mesh m = {positions, NULL, face, 10, 10, 0};

  SparseMat* edges = create_edges(&m);

  preserve_bounds(&m, q, edges);

  sparse_free(edges);

  // 0 - 2 NOT equal
  q_not_equal(test_case, q_old, q, 0, 3 * 16);
  // 3, 4 equal
  q_equal(test_case, q_old, q, 3 * 16, 5 * 16);
  // 5 - 9 NOT equal
  q_not_equal(test_case, q_old, q, 5 * 16, 10 * 16);

  printf("✓ %s\n", test_case);
}